﻿// Copyright 2005, 2006 - Morten Nielsen (www.iter.dk)
//
// This file is part of SharpMap.
// SharpMap is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// SharpMap is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public License
// along with SharpMap; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

using System;
using System.Collections.Generic;
using System.Text;

namespace Petra.Gis.ReferenceSystemServices
{
  /// <summary>
  /// A 2D cartographic coordinate system.
  /// </summary>
  public class ProjectedCoordinateSystem : HorizontalCoordinateSystem
  {

    
    /// <summary>
    /// xaml constr.
    /// </summary>
    public ProjectedCoordinateSystem() { }




    /// <summary>
    /// Initializes a new instance of a projected coordinate system
    /// </summary>
    /// <param name="geographicCoordinateSystem">Geographic coordinate system</param>
    /// <param name="storageUnit">Data storage unit</param>
    /// <param name="projection">Projection</param>
    /// <param name="axes">Axis info</param>
    /// <param name="metadata">Coordinate system metadata</param>
    public ProjectedCoordinateSystem(GeographicCoordinateSystem geographicCoordinateSystem,
      DistanceUnit storageUnit, Projection projection, AxisList axes,
      Metadata metadata)
      : base(geographicCoordinateSystem.HorizontalDatum, storageUnit, axes, metadata)
    {
      _GeographicCoordinateSystem = geographicCoordinateSystem;
      _Projection = projection;
    }

    #region Predefined projected coordinate systems
    /*
		/// <summary>
		/// Universal Transverse Mercator - WGS84
		/// </summary>
		/// <param name="Zone">UTM zone</param>
		/// <param name="ZoneIsNorth">true of Northern hemisphere, false if southern</param>
		/// <returns>UTM/WGS84 coordsys</returns>
		public static ProjectedCoordinateSystem WGS84_UTM(int Zone, bool ZoneIsNorth)
		{
			ParameterInfo pInfo = new ParameterInfo();
			pInfo.Add("latitude_of_origin", 0);
			pInfo.Add("central_meridian", Zone * 6 - 183);
			pInfo.Add("scale_factor", 0.9996);
			pInfo.Add("false_easting", 500000);
			pInfo.Add("false_northing", ZoneIsNorth ? 0 : 10000000);
			Projection proj = new Projection(String.Empty,String.Empty,pInfo,AngularUnit.Degrees,
				SharpMap.SpatialReference.LinearUnit.Metre,Ellipsoid.WGS84,
				"Transverse_Mercator", "EPSG", 32600 + Zone + (ZoneIsNorth ? 0 : 100), String.Empty, String.Empty, String.Empty);

			return new ProjectedCoordinateSystem("Large and medium scale topographic mapping and engineering survey.",
				SharpMap.SpatialReference.GeographicCoordinateSystem.WGS84,
				SharpMap.SpatialReference.LinearUnit.Metre, proj, pInfo,
				"WGS 84 / UTM zone " + Zone.ToString() + (ZoneIsNorth ? "N" : "S"), "EPSG", 32600 + Zone + (ZoneIsNorth ? 0 : 100),
				String.Empty,String.Empty,string.Empty);
			
		}*/

    #endregion

    #region ProjectedCoordinateSystem Members


    private GeographicCoordinateSystem _GeographicCoordinateSystem;

    /// <summary>
    /// Gets or sets the GeographicCoordinateSystem.
    /// </summary>
    public GeographicCoordinateSystem GeographicCoordinateSystem
    {
      get { return _GeographicCoordinateSystem; }
      set { _GeographicCoordinateSystem = value; }
    }




    private Projection _Projection;

    /// <summary>
    /// Gets or sets the projection
    /// </summary>
    public Projection Projection
    {
      get { return _Projection; }
      set { _Projection = value; }
    }




    /// <summary>
    /// Checks whether the values of this instance is equal to the values of another instance.
    /// Only parameters used for coordinate system are used for comparison.
    /// Name, abbreviation, authority, alias and remarks are ignored in the comparison.
    /// </summary>
    /// <param name="obj"></param>
    /// <returns>True if equal</returns>
    public override bool EqualParams(CoordinateSystem obj, bool ignoreStorageUnits)
    {
      if (!(obj is ProjectedCoordinateSystem))
        return false;
      ProjectedCoordinateSystem pcs = obj as ProjectedCoordinateSystem;

      if (pcs.Dimension != this.Dimension)
        return false;
      for (int i = 0; i < pcs.Dimension; i++)
      {
        if (pcs.Axes[i].Orientation != this.Axes[i].Orientation)
          return false;
        if (!pcs.StorageUnit.EqualParams(this.StorageUnit))
          return false;
      }

      if(ignoreStorageUnits)
        return pcs.GeographicCoordinateSystem.EqualParams(this.GeographicCoordinateSystem, false) &&
            pcs.HorizontalDatum.EqualParams(this.HorizontalDatum) &&
            pcs.Projection.EqualParams(this.Projection);
      else
        return pcs.GeographicCoordinateSystem.EqualParams(this.GeographicCoordinateSystem, false) &&
            pcs.HorizontalDatum.EqualParams(this.HorizontalDatum) &&
            pcs.StorageUnit.EqualParams(this.StorageUnit) &&
            pcs.Projection.EqualParams(this.Projection);
    }

    #endregion
  }
}
